package com.smarttest.common.util;
/**
* <p>Title: DataRetrieveHandlers.java</p>
* <p>Description: </p>
* <p>Company: www.huoyunren.com</p>
* @author duanxiangyun
* @date 2016年6月24日
* @version 1.0
*/


import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.testng.Assert;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.g7s.test.utils.Excel.DataHandlers;

public class DataRetrieveHandlers {

	/**
	 * 获得测试数据的公共方法
	 * @param filename
	 * @param sheetname
	 * @param totaldata 该case所有URL、参数及数据
	 * @param testdatas 该case所有数据
	 * @return Object[][]
	 */
	static Object[][] getTestDataFromExcel (String filename, String sheetname,Object totaldata[][],Object testdatas[][]) {
		String interfacedetail = totaldata[0][1].toString();
		String url = totaldata[1][1].toString();
		String sendMethod = totaldata[2][1].toString();
		Boolean dataToJson = Boolean.parseBoolean(totaldata[3][1].toString());
		Map<String,Integer> m = new HashMap<String,Integer>();
		Map<String,String> params = new HashMap<String,String>();
		for (int i = 0; i < totaldata[4].length;i++) {
			Object param = totaldata[4][i];

			if (param != null && !param.toString().isEmpty()) {
				if (param.toString().equalsIgnoreCase("expectResult") && i != 8) {
					Assert.fail("expectResult列必须位于第9实列，位于用例描述之前");
				}
				if (param.toString().equalsIgnoreCase("resultAlias") && (totaldata[4].length == 10 ? i != 8 : i != 9)) {
					Assert.fail("resultAlias列必须位于第9或者第10实列，位于用例描述之前");
				}
				try {
					params.put(param.toString(), totaldata[5][i].toString());
				}
				catch(IllegalArgumentException e) {
					e.printStackTrace();
					Assert.fail("excel中传入接口的参数不能有重复的");
				}	
			}
		}
		for (int i = 0; i < totaldata[6].length;i++) {
			Object param = totaldata[6][i];
			if (param != null && !param.toString().isEmpty()) {
				try{
					m.put(param.toString(),i);
				}
				catch(IllegalArgumentException e) {
					e.printStackTrace();
					Assert.fail("excel中作为数据源传入的参数不能有重复的");
				}	
			}
		}
		
		List<Object[]> l = new ArrayList<Object[]>();
		for (int i = 0; i < testdatas.length; i++) {
			if (testdatas[i][0].toString().equalsIgnoreCase("N")) {
				continue;
			}
			else if (InterfaceUtils.getTlevel().equals("1") && !testdatas[i][1].equals("1")) {
				continue;
			}
			else {				
				Object [] tmpArr = new Object[4+testdatas[0].length - 2];
				for (int j = 0; j < tmpArr.length; j++) {
					if (j == 0) {
						tmpArr[j] = interfacedetail;
					}
					else if (j == 1) {
						tmpArr[j] = url;
					}
					else if (j==2){
						tmpArr[j] = sendMethod;
					}
					else if (j==3) {
						Map<String,String> params_copy = new HashMap<String,String>();
						params_copy.putAll(params);
						Map<String,String> tmpmap = new HashMap<String,String>();
						String removekey = null;
						loop:
						for (String key : params_copy.keySet()) {
							String value = params_copy.get(key);
							if (value.contains("(") && value.endsWith(")")) {
								String tmp[] = value.substring(value.indexOf("(")+1, value.indexOf(")")).split(",");
								for (int k = 0; k < tmp.length; k++) {
									while(params_copy.containsKey(tmp[k])) {
										tmp[k] = params_copy.get(tmp[k]);
									}
									while(m.containsKey(tmp[k])) {
										if (m.get(tmp[k]) == 3) {
											tmp[k] = testdatas[i][2].toString();
										}	
									}
								}
								value = value.substring(0, value.indexOf("(")+1) + StringUtils.join(tmp, ",") + ")";
								params_copy.put(key, value);
							}
							else {
								while(params_copy.containsKey(value)) {
									value = params_copy.get(value);
								}
								while(m.containsKey(value)) {
									if (m.get(value) == 3) {									
										if (dataToJson) {
											value = testdatas[i][2].toString();
										}
										else {
											removekey = key;																						
											continue loop;
										}
									}
								}
								params_copy.put(key, value);
							}
						}
						JSONObject jo = new JSONObject();
						try{
							jo = JSONObject.parseObject(testdatas[i][2].toString());
						}
						catch(JSONException e) {
							e.printStackTrace();
							Assert.fail("testdata格式有误，请传入正确的JSON格式");
						}
						for (Object jo_key : jo.keySet()) {
							tmpmap.put(jo_key.toString(), jo.get(jo_key).toString());
						}
						if (removekey != null) {
							params_copy.remove(removekey);
						}
						if (!dataToJson) {
							params_copy.putAll(tmpmap);
						}
						tmpArr[j] = params_copy;
					}
					else {
						Object o = testdatas[i][j-2];
						String s = totaldata[6][j-1].toString();
						if (s.equalsIgnoreCase("resultAlias") || s.equalsIgnoreCase("expectReturn")) {
							Map<String, String> mm = new HashMap<String, String>();
							mm.put(s, o.toString());
							tmpArr[j] = mm;
						}
						else if (!s.isEmpty()){
							tmpArr[j] = o;
						}
					}
				}
				l.add(tmpArr);
			}
		}
		Object [][] paramsArr = new Object [l.size()][];
		paramsArr = l.toArray(paramsArr);
		return paramsArr;
	}
	/**
	 * 获得excel表单个接口各个场景的测试数据
	 * @param filename 文件名
	 * @param sheetname 表名
	 * @return Object[][]
	 */
	public static Object[][] getTestData (String filename, String sheetname) {
		Object totaldata[][] = DataHandlers.getInstance(filename).getData(sheetname,0,-1,0,-1,true);
		Object [][] testdatas = DataHandlers.getInstance(filename).getData(sheetname, 7,-1, 1,-1,true);
		return getTestDataFromExcel(filename, sheetname, totaldata, testdatas);
	}
	private static String bracket = "BRACKET";
	/**
	 * 获得excel表多个接口复杂场景的测试数据
	 * @param filename 文件名
	 * @param sheetname 表名
	 * @return Object[][]
	 * @throws Exception 
	 */
	public static String[][] getTestDataForDuplicateScene (String filename, String sheetname) throws Exception {
		Object totaldata[][] = DataHandlers.getInstance(filename).getData(sheetname);
		Object caseid[][] = DataHandlers.getInstance(filename).getData(sheetname, 1,-1, 0,1,true);
		List<Integer> l = new ArrayList<Integer>();
		for (int i = 0; i < caseid.length; i++) {
			if (!caseid[i][0].toString().isEmpty())
			{
				l.add(i);
			}
				
		}
		Map<Integer, Integer> nums = getMiddleNums(l.toArray());		
		Map<String, String> tmpmap = new HashMap<String,String>();	
		for (Integer i : nums.keySet()) {
			Integer value = nums.get(i);
			Object currentCaseTotaldata[][] = DataHandlers.getInstance(filename).getData(sheetname, i+1,value-i+1, 1,-1,true);
			Object testdata[][] = DataHandlers.getInstance(filename).getData(sheetname, i+8,value-(i+7)+1, 2,8,true);
			Object casesdata[][] = getTestDataFromExcel(filename, sheetname, currentCaseTotaldata, testdata);
			@SuppressWarnings("unchecked")
			Map<String,String> params = (Map<String, String>) casesdata[0][3];	
			String data = casesdata[0][4].toString();
			for (String key : tmpmap.keySet()) {
				if (data.contains(key)) {
					data = data.replaceAll(key, tmpmap.get(key));
				}
			}		
			JSONObject iReturn = InterfaceUtils.callInterface(casesdata[0][1].toString(), casesdata[0][2].toString(), params);
			InterfaceUtils.InterfaceCheck(iReturn,data, casesdata[0][5].toString(), casesdata[0][6].toString(),casesdata[0][7].toString(),casesdata[0][8].toString());
			String resultname = currentCaseTotaldata[6][7].toString();
			String result = InterfaceUtils.getResult(iReturn).toString();
			String tmp_name = currentCaseTotaldata[6][8].toString();
			String tmp = casesdata[0][10].toString();
			if (tmp.contains(resultname)) {
				tmp = tmp.replaceAll(resultname, result);
			}
			if (tmp.contains("(") && tmp.endsWith(")")) {
				String tmpstr = null;
				if (tmp.contains("[") && tmp.contains("]")) {					
					tmpstr = tmp.substring(tmp.indexOf("[")+1, tmp.indexOf("]"));
					tmp = tmp.substring(0,tmp.indexOf("[")+1)+bracket+tmp.substring(tmp.indexOf("]"));
				}
				else if (tmp.contains("{") && tmp.contains("}")) {
					tmpstr = tmp.substring(tmp.indexOf("{")+1, tmp.indexOf("}"));
					tmp = tmp.substring(0,tmp.indexOf("{")+1)+bracket+tmp.substring(tmp.indexOf("}"));
				}
				Object parammeters[] = tmp.substring(tmp.indexOf("(")+1, tmp.lastIndexOf(")")).split(",");
				for (int j = 0; j < parammeters.length; j++) {
					String pm = parammeters[j].toString();
					if (pm.contains(bracket)) {
						parammeters[j] = pm.replaceAll(bracket, tmpstr);
					}	
				}
				parammeters = InterfaceUtils.trimArr(parammeters);
				Class<?>[] cArg = new Class[parammeters.length];
				for (int j = 0; j < cArg.length; j++) {
					cArg[j] = String.class;
				}
				String tmparr[] = tmp.split("\\(", 2);
				String method = tmparr[0].trim();
				InterfaceUtils inter = new InterfaceUtils();
				Class<?> cls = InterfaceUtils.class;
				Method m1 = cls.getDeclaredMethod(method, cArg);
				tmp = m1.invoke(inter,
						parammeters).toString();
			}
			tmpmap.put(tmp_name, tmp);
		}
		String assertStr = totaldata[totaldata.length - 1][1].toString();
		String casedetail = totaldata[0][1].toString();
		for (String key : tmpmap.keySet()) {
			if (assertStr.contains(key)) {
				assertStr = assertStr.replaceAll(key, tmpmap.get(key));
			}
		}
		String [][] s = {{casedetail,assertStr,""}};
		return s;
	}
	/**
	 * 取int数组排序后每两个数据之间的值，如[1,5,9],那么会得到3,4 和6,7,8
	 * @param arr
	 * @return
	 */
	public static Map<Integer, Integer> getMiddleNums(Object []arr) {
		Arrays.sort(arr);
		Map<Integer,Integer> m = new LinkedHashMap<Integer, Integer>();
		for (int i = 0; i < arr.length - 1; i++) {
			m.put(Integer.parseInt(arr[i].toString())+1, Integer.parseInt(arr[i+1].toString())-1);
		}
		return m;
	}
}
